﻿using System;
using BITS.Library.Refelection.Extensions;

namespace BITS.PreCompiler.CSharp.Syntax.Extensions
{
    public static class SystemTypeExtension
    {
        public static Interface ToInterface(this System.Type @this, Interface @interface = null, Boolean @inherit = true)
        {
            if (!@this.IsInterface)
                throw new ApplicationException(String.Format(
                    "Type:'{0}' is not a interface.", @this.FullName));

            @interface = @interface ?? new Interface(@this.Name);

            foreach (var propertyInfo in @this.GetProperties())
            {
                var property = new InterfaceProperty(propertyInfo.Name);

                property.WithReturnType(propertyInfo.PropertyType.ToGenericTypeFullName());

                if (propertyInfo.GetGetMethod() != null)
                    property.WithGetter();

                if (propertyInfo.GetSetMethod() != null)
                    property.WithSetter();

                @interface.Add(property);
            }

            if (!@inherit)
                return @interface;

            foreach (var i in @this.GetAllImplementedInterfaces())
                @interface.AddImplementor(i.ToInterface());

            return @interface;
        }

        public static Class ToClass(this System.Type @this, Class @class = null, Boolean @inherit = true)
        {
            if (!@this.IsClass)
                throw new ApplicationException(String.Format(
                    "Type:'{0}' is not a class.", @this.FullName));

            @class = @class ?? new Class();

            if (!@inherit)
                return @class;

            return @class;
        }

        public static Class ToClass(this Interface @this, Class @class = null, String name = null)
        {
            var className = @this.Name;

            // Remove the beginning 'I' from name.
            if (className.Length > 1 && className[0] == 'I' && Char.IsUpper(className[1]))
                className = className.Substring(1);

            @class = @class ?? new Class(name ?? className);

            foreach (var property in @this.Properties)
                @class.Add(property.WithExplicitInterface(@this));

            //foreach (Interface implementor in @this.Implementors)
            //{
            //    foreach (var property in implementor.Properties)
            //        @class.Add(property.WithExplicitInterface(implementor));
            //}

            return @class;
        }

        public static String ToClassName(this System.Type @this)
        {
            if (!@this.IsInterface)
                throw new ApplicationException(String.Format(
                    "Type:'{0}' is not a interface.", @this.FullName));

            // Remove the beginning 'I' from name.
            if (@this.Name.Length > 1 && @this.Name[0] == 'I' && Char.IsUpper(@this.Name[1]))
                return @this.Name.Substring(1);

            return @this.Name;
        }
    }
}
